﻿using Sustainalytics.ClientDW.Entities;
using Sustainalytics.ClientDW.Entities.Universes;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.Universes.Synchronization
{
    public class UniverseResearchCoverage
    {

        private IEnumerable<UniverseCompany> ProcessCoverageEnhance(IEnumerable<UniverseCompany> universeCompanies,
            IList<CorporateData> corporateDataList)
        {
            var compUnivDict = universeCompanies.GroupBy(uc => uc.CompanyId, uc => uc.UniverseId, (key, g) => new { CompanyId = key, UniverseIds = g.ToList() }).ToDictionary(cd => cd.CompanyId, cd => cd.UniverseIds);
            var universesAccountsDict = universeCompanies.Select(uc => new { uc.UniverseId, uc.AccountId }).Distinct().ToDictionary(ua => ua.UniverseId, ua => ua.AccountId);
            var lst=new List<UniverseCompany>();
            foreach (var corporateData in corporateDataList)
            {
                var lstUniv = new List<int>();
                if (corporateData.ResearchParentId != null) //check if the current is coverage or not
                {
                    var data = corporateDataList.Where(a => a.ResearchParentId == corporateData.ResearchParentId).ToList(); //check for sibblings
                    foreach (var aux in data)
                    {
                        if (compUnivDict.ContainsKey(aux.Id))
                        {
                            lstUniv.AddRange(compUnivDict[aux.Id].ToList());
                        }
                    }
                    if (compUnivDict.ContainsKey(corporateData.ResearchParentId.Value))
                    {
                        lstUniv.AddRange(compUnivDict[corporateData.ResearchParentId.Value].ToList());
                    }
                    if (compUnivDict.ContainsKey(corporateData.Id))
                    {
                        lstUniv.AddRange(compUnivDict[corporateData.Id].ToList());
                    }
                }
                else //it is not coverage we check for current entity and all it's sons
                {
                    if (compUnivDict.ContainsKey(corporateData.Id))
                    {
                        lstUniv.AddRange(compUnivDict[corporateData.Id]);
                    }
                    //get all it's sons

                    var data = corporateDataList.Where(a => a.ResearchParentId == corporateData.Id).ToList(); //check for sons
                    foreach (var aux in data)
                    {
                        if (compUnivDict.ContainsKey(aux.Id))
                        {
                            lstUniv.AddRange(compUnivDict[aux.Id].ToList());
                        }
                    }
                }
                lstUniv = lstUniv.Distinct().ToList();
                foreach (var i in lstUniv)
                {
                    lst.Add(new UniverseCompany() { CompanyId = corporateData.Id, CIQID = corporateData.CapitalIqId.ToString(), AccountId = universesAccountsDict[i], UniverseId = i });                    
                }

            }
            return lst; //TODO to be used siblings and coverage ids if there will be any, right now this method is a little bit slow

        }

        public IEnumerable<UniverseCompany> ProcessCoverage(IEnumerable<UniverseCompany> universeCompanies, IList<CorporateData> corporateDataList)
        {
            return ProcessCoverageEnhance(universeCompanies, corporateDataList);
        }
    }
}
